package cn.kgc.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.pinyin.PinyinUtil;
import cn.kgc.entity.Menus;
import cn.kgc.entity.RolesMenus;
import cn.kgc.form.MenusAddForm;
import cn.kgc.form.MenusUpdateForm;
import cn.kgc.service.MenusService;
import cn.kgc.service.RolesMenusService;
import cn.kgc.util.ResultConstant;
import cn.kgc.util.SystemUtil;
import cn.kgc.util.exception.HttpException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

/**
 * @author wangyue
 * @version 1.0
 */
@RestController
@RequestMapping("/menus")
@Api
@Validated
@Slf4j
@CrossOrigin
@SuppressWarnings("all")
public class MenusController {
    @Resource
    private MenusService menusService;

    @Resource
    private RolesMenusService rolesMenusService;

    @PostMapping("/save")
    @ApiOperation(value = "添加菜单")
    public boolean save(@RequestBody MenusAddForm form) {
        //判断菜单名字是否重复
        checkMenuNameRepeat(form.getMenuName(), null);
        //获得菜单编码
        String menuCode = PinyinUtil.getFirstLetter(form.getMenuName(), "");
        //创建菜单对象
        Menus menus = new Menus();
        //将要新增的数据拷贝带menus对象中
        BeanUtil.copyProperties(form, menus);
        //设置菜单的编码
        menus.setMenuCode(menuCode);
        return menusService.save(menus);
    }

    @DeleteMapping("/delete/{id}")
    @ApiOperation(value = "删除菜单")
    @CacheEvict(value = "menus", key = "#id")
    public boolean delete(@PathVariable("id") Long id) {
        //1 判断菜单下是否有子菜单，如果有则不能删除
        checkMenuIsHasChild(id);
        //2 如果菜单被使用则不能删除
        checkMenuIsUsed(id);
        //3 删除菜单
        return rolesMenusService.removeById(id);
    }

    private void checkMenuIsUsed(Long menuId) {
        LambdaQueryWrapper<RolesMenus> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RolesMenus::getMid, menuId);
        if (rolesMenusService.count(queryWrapper) > 0) {
            throw new HttpException(ResultConstant.MENU_IS_USED);
        }
    }

    private void checkMenuIsHasChild(Long menuId) {
        LambdaQueryWrapper<Menus> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Menus::getParentId, menuId);
        if (menusService.count(queryWrapper) > 0) {
            throw new HttpException(ResultConstant.MENU_HAS_CHTLD);
        }
    }

    @PostMapping("/update")
    @ApiOperation("更新菜单信息")
    @CacheEvict(value = "menus", key = "#form.getId()")
    public boolean update(@RequestBody MenusUpdateForm form) {
        checkMenuNameRepeat(form.getMenuName(), form.getId());
        //根据菜单的名称获得对应的拼音 当成菜单的编码
        String menuCode = PinyinUtil.getFirstLetter(form.getMenuName(), "");
        //原来的菜单的信息
        Menus menus = menusService.getById(form.getId());
        if (menus != null) {
            //将要更新的数据拷贝到menus对象中
            BeanUtil.copyProperties(form, menus);
            //将menus对象更新到数据库中
            return menusService.updateById(menus);
        }
        return false;
    }


    private void checkMenuNameRepeat(String menuName, Long menuId) {
        LambdaQueryWrapper<Menus> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Menus::getMenuName, menuName);
        queryWrapper.ne(menuId != null, Menus::getId, menuId);
        if (menusService.count(queryWrapper) > 0) {
            throw new HttpException(ResultConstant.MENU_NAME_REPEAT);
        }
    }


    @GetMapping("/detail/{id}")
    @ApiOperation(value = "查询菜单详细信息")
    @Cacheable(value = "menus", key = "#id")
    // key==>   menus::12
    // value==> 方法中返回的菜单对象
    public Menus detail(@PathVariable int id) {
        return menusService.getById(id);
    }

    @PostMapping("/list")
    @ApiOperation(value = "查询菜单列表")
    public List<Menus> list(@RequestBody Map<String, Object> params) {
        //1 如果传入菜单编码和菜单名称  按照菜单编码和菜单名称查询菜单
        String menuCode = MapUtil.getStr(params, "menuCode");
        String menuName = MapUtil.getStr(params, "menuName");
        LambdaQueryWrapper<Menus> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(
                StrUtil.isNotBlank(menuCode),
                Menus::getMenuCode,
                menuCode
        );
        queryWrapper.eq(
                StrUtil.isNotBlank(menuName),
                Menus::getMenuName,
                menuName
        );
        List<Menus> list = menusService.list(queryWrapper);
        if (StrUtil.isBlank(menuCode) && StrUtil.isBlank(menuName)) {
            //2 如果没有传入参数成一个JSON格式的树形结构返回给前端
            list = SystemUtil.tree(list);
        }
        return list;
    }
}